Better tie together ContentType and Permissions.

Since most content types (e.g. typeCode) have a 
preferred Permission, add a function to do that mapping.
Then hook up to YAML Reader and Writer such that
the 'permissions:' key does not need to be specified unless
overriding what the content type prefers.

llvm-svn: 171929
This commit is contained in:
Nick Kledzik 2013-01-09 01:17:12 +00:00
parent b696c36fcd
commit cc3d2dca60
5 changed files with 155 additions and 9 deletions

View File

@ -123,6 +123,7 @@ public:
typeLiteral16, // a sixteen-btye read-only constant typeLiteral16, // a sixteen-btye read-only constant
typeData, // read-write data typeData, // read-write data
typeZeroFill, // zero-fill data typeZeroFill, // zero-fill data
typeConstData, // read-only data after dynamic linker is done
typeObjC1Class, // ObjC1 class [Darwin] typeObjC1Class, // ObjC1 class [Darwin]
typeLazyPointer, // pointer through which a stub jumps typeLazyPointer, // pointer through which a stub jumps
typeLazyDylibPointer, // pointer through which a stub jumps [Darwin] typeLazyDylibPointer, // pointer through which a stub jumps [Darwin]
@ -152,6 +153,7 @@ public:
permRWX = 8 + 4 + 2, // mapped readable and writable and executable permRWX = 8 + 4 + 2, // mapped readable and writable and executable
permRW_L = 8 + 4 + 1, // initially mapped r/w, then made read-only permRW_L = 8 + 4 + 1, // initially mapped r/w, then made read-only
// loader writable // loader writable
permUnknown = 16 // unknown or invalid permissions
}; };
enum SectionChoice { enum SectionChoice {
@ -230,7 +232,7 @@ public:
/// ///
/// A function atom is R_X, a global variable is RW_, and a read-only constant /// A function atom is R_X, a global variable is RW_, and a read-only constant
/// is R__. /// is R__.
virtual ContentPermissions permissions() const = 0; virtual ContentPermissions permissions() const;
/// \brief only applicable to ARM code. Tells the linker if the code uses /// \brief only applicable to ARM code. Tells the linker if the code uses
/// thumb or arm instructions. The linker needs to know this to set the low /// thumb or arm instructions. The linker needs to know this to set the low
@ -286,6 +288,9 @@ public:
return a->definition() == definitionRegular; return a->definition() == definitionRegular;
} }
/// Utility for deriving permissions from content type
static ContentPermissions permissions(ContentType type);
protected: protected:
// DefinedAtom is an abstract base class. Only subclasses can access // DefinedAtom is an abstract base class. Only subclasses can access
// constructor. // constructor.

View File

@ -1,6 +1,7 @@
set(LLVM_LINK_COMPONENTS support) set(LLVM_LINK_COMPONENTS support)
add_lld_library(lldCore add_lld_library(lldCore
DefinedAtom.cpp
Error.cpp Error.cpp
File.cpp File.cpp
InputFiles.cpp InputFiles.cpp

View File

@ -0,0 +1,78 @@
//===- DefinedAtom.cpp ------------------------------------------*- C++ -*-===//
//
// The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/Support/ErrorHandling.h"
#include "lld/Core/DefinedAtom.h"
namespace lld {
DefinedAtom::ContentPermissions DefinedAtom::permissions() const {
// By default base permissions on content type.
return permissions(this->contentType());
}
// Utility function for deriving permissions from content type
DefinedAtom::ContentPermissions DefinedAtom::permissions(ContentType type) {
switch (type) {
case typeCode:
case typeResolver:
case typeBranchIsland:
case typeBranchShim:
case typeStub:
case typeStubHelper:
return permR_X;
case typeConstant:
case typeCString:
case typeUTF16String:
case typeCFI:
case typeLSDA:
case typeLiteral4:
case typeLiteral8:
case typeLiteral16:
case typeDTraceDOF:
case typeCompactUnwindInfo:
return permR__;
case typeData:
case typeZeroFill:
case typeObjC1Class:
case typeLazyPointer:
case typeLazyDylibPointer:
case typeThunkTLV:
return permRW_;
case typeGOT:
case typeConstData:
case typeCFString:
case typeInitializerPtr:
case typeTerminatorPtr:
case typeCStringPtr:
case typeObjCClassPtr:
case typeObjC2CategoryList:
case typeTLVInitialData:
case typeTLVInitialZeroFill:
case typeTLVInitializerPtr:
return permRW_L;
case typeUnknown:
case typeTempLTO:
case typeFirstInSection:
case typeLastInSection:
return permUnknown;
}
llvm_unreachable("unknown content type");
}
} // namespace

View File

@ -366,12 +366,13 @@ struct ScalarEnumerationTraits<lld::DefinedAtom::DeadStripKind> {
template <> template <>
struct ScalarEnumerationTraits<lld::DefinedAtom::ContentPermissions> { struct ScalarEnumerationTraits<lld::DefinedAtom::ContentPermissions> {
static void enumeration(IO &io, lld::DefinedAtom::ContentPermissions &value) { static void enumeration(IO &io, lld::DefinedAtom::ContentPermissions &value) {
io.enumCase(value, "---", lld::DefinedAtom::perm___); io.enumCase(value, "---", lld::DefinedAtom::perm___);
io.enumCase(value, "r--", lld::DefinedAtom::permR__); io.enumCase(value, "r--", lld::DefinedAtom::permR__);
io.enumCase(value, "r-x", lld::DefinedAtom::permR_X); io.enumCase(value, "r-x", lld::DefinedAtom::permR_X);
io.enumCase(value, "rw-", lld::DefinedAtom::permRW_); io.enumCase(value, "rw-", lld::DefinedAtom::permRW_);
io.enumCase(value, "rwx", lld::DefinedAtom::permRWX); io.enumCase(value, "rwx", lld::DefinedAtom::permRWX);
io.enumCase(value, "rw-l", lld::DefinedAtom::permRW_L); io.enumCase(value, "rw-l", lld::DefinedAtom::permRW_L);
io.enumCase(value, "unknown", lld::DefinedAtom::permUnknown);
} }
}; };
@ -390,6 +391,8 @@ struct ScalarEnumerationTraits<lld::DefinedAtom::ContentType> {
lld::DefinedAtom::typeData); lld::DefinedAtom::typeData);
io.enumCase(value, "zero-fill", io.enumCase(value, "zero-fill",
lld::DefinedAtom::typeZeroFill); lld::DefinedAtom::typeZeroFill);
io.enumCase(value, "const-data",
lld::DefinedAtom::typeConstData);
io.enumCase(value, "got", io.enumCase(value, "got",
lld::DefinedAtom::typeGOT); lld::DefinedAtom::typeGOT);
io.enumCase(value, "resolver", io.enumCase(value, "resolver",
@ -970,8 +973,10 @@ struct MappingTraits<const lld::DefinedAtom*> {
StringRef()); StringRef());
io.mapOptional("dead-strip", keys->_deadStrip, io.mapOptional("dead-strip", keys->_deadStrip,
lld::DefinedAtom::deadStripNormal); lld::DefinedAtom::deadStripNormal);
// default permissions based on content type
io.mapOptional("permissions", keys->_permissions, io.mapOptional("permissions", keys->_permissions,
lld::DefinedAtom::permR_X); lld::DefinedAtom::permissions(
keys->_contentType));
io.mapOptional("references", keys->_references); io.mapOptional("references", keys->_references);
} }
}; };

View File

@ -0,0 +1,57 @@
# RUN: lld-core %s | FileCheck %s
#
# Test permissions for known content types are implicit, but can be overridden.
#
---
defined-atoms:
- name: one
type: code
- name: two
type: data
permissions: rw-
- name: three
type: const-data
- name: four
type: unknown
- name: oddCode
type: code
permissions: rwx
- name: oddData
type: data
permissions: rwx
- name: oddConstData
type: const-data
permissions: rw-
- name: oddUnknown
type: unknown
permissions: rw-
...
# CHECK: ---
# CHECK: defined-atoms:
# CHECK: - name: one
# CHECK-NOT: permissions:
# CHECK: - name: two
# CHECK-NOT: permissions:
# CHECK: - name: three
# CHECK-NOT: permissions:
# CHECK: - name: four
# CHECK-NOT: permissions:
# CHECK: - name: oddCode
# CHECK: permissions: rwx
# CHECK: - name: oddData
# CHECK: permissions: rwx
# CHECK: - name: oddConstData
# CHECK: permissions: rw-
# CHECK: - name: oddUnknown
# CHECK: permissions: rw-
# CHECK: ...