forked from OSchip/llvm-project
[llvm-objcopy] Fix sh_link
This diff fixes sh_link for various types of sections (i.e. for SHT_ARM_EXIDX, SHT_HASH). In particular, this change enables us to use llvm-objcopy with clang -gsplit-dwarf for the target android-arm. Test plan: make check-all Differential revision: https://reviews.llvm.org/D45851 llvm-svn: 330478
This commit is contained in:
parent
334c379e32
commit
52db4335b3
|
@ -0,0 +1,48 @@
|
|||
# RUN: yaml2obj %s > %t
|
||||
# RUN: llvm-objcopy -remove-section=.text.bar %t %t2
|
||||
# RUN: llvm-readobj -sections %t2 | FileCheck %s
|
||||
|
||||
# CHECK: Index: 2
|
||||
# CHECK-NEXT: Name: .ARM.exidx.text.foo (1)
|
||||
# CHECK-NEXT: Type: SHT_ARM_EXIDX (0x70000001)
|
||||
# CHECK: Address: 0x0
|
||||
# CHECK-NEXT: Offset: 0x34
|
||||
# CHECK-NEXT: Size: 0
|
||||
# CHECK-NEXT: Link: 1
|
||||
# CHECK-NEXT: Info: 0
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS32
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_REL
|
||||
Machine: EM_ARM
|
||||
Flags: [ EF_ARM_EABI_VER5 ]
|
||||
Sections:
|
||||
- Name: .text.bar
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
|
||||
AddressAlign: 0x0000000000000004
|
||||
Content: ''
|
||||
- Name: .text.foo
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
|
||||
AddressAlign: 0x0000000000000004
|
||||
Content: ''
|
||||
- Name: .ARM.exidx.text.foo
|
||||
Type: SHT_ARM_EXIDX
|
||||
Flags: [ SHF_ALLOC, SHF_LINK_ORDER ]
|
||||
Link: .text.foo
|
||||
AddressAlign: 0x0000000000000004
|
||||
Content: ''
|
||||
Symbols:
|
||||
Local:
|
||||
- Name: .text.bar
|
||||
Type: STT_SECTION
|
||||
Section: .text.bar
|
||||
- Name: .text.foo
|
||||
Type: STT_SECTION
|
||||
Section: .text.foo
|
||||
- Name: .ARM.exidx.text.foo
|
||||
Type: STT_SECTION
|
||||
Section: .ARM.exidx.text.foo
|
|
@ -1,3 +1,3 @@
|
|||
# RUN: not llvm-objcopy -R .dynstr %p/Inputs/dynsym.so %t 2>&1 >/dev/null | FileCheck %s
|
||||
|
||||
# CHECK: String table .dynstr cannot be removed because it is referenced by the section .dynsym
|
||||
# CHECK: Section .dynstr cannot be removed because it is referenced by the section .dynsym
|
||||
|
|
|
@ -353,9 +353,9 @@ void DynamicRelocationSection::accept(SectionVisitor &Visitor) const {
|
|||
Visitor.visit(*this);
|
||||
}
|
||||
|
||||
void SectionWithStrTab::removeSectionReferences(const SectionBase *Sec) {
|
||||
if (StrTab == Sec) {
|
||||
error("String table " + StrTab->Name +
|
||||
void Section::removeSectionReferences(const SectionBase *Sec) {
|
||||
if (LinkSection == Sec) {
|
||||
error("Section " + LinkSection->Name +
|
||||
" cannot be removed because it is "
|
||||
"referenced by the section " +
|
||||
this->Name);
|
||||
|
@ -367,23 +367,18 @@ void GroupSection::finalize() {
|
|||
this->Link = SymTab->Index;
|
||||
}
|
||||
|
||||
bool SectionWithStrTab::classof(const SectionBase *S) {
|
||||
return isa<DynamicSymbolTableSection>(S) || isa<DynamicSection>(S);
|
||||
void Section::initialize(SectionTableRef SecTable) {
|
||||
if (Link != ELF::SHN_UNDEF)
|
||||
LinkSection =
|
||||
SecTable.getSection(Link, "Link field value " + Twine(Link) +
|
||||
" in section " + Name + " is invalid");
|
||||
}
|
||||
|
||||
void SectionWithStrTab::initialize(SectionTableRef SecTable) {
|
||||
auto StrTab =
|
||||
SecTable.getSection(Link, "Link field value " + Twine(Link) +
|
||||
" in section " + Name + " is invalid");
|
||||
if (StrTab->Type != SHT_STRTAB) {
|
||||
error("Link field value " + Twine(Link) + " in section " + Name +
|
||||
" is not a string table");
|
||||
}
|
||||
setStrTab(StrTab);
|
||||
void Section::finalize() {
|
||||
if (LinkSection)
|
||||
this->Link = LinkSection->Index;
|
||||
}
|
||||
|
||||
void SectionWithStrTab::finalize() { this->Link = StrTab->Index; }
|
||||
|
||||
void GnuDebugLinkSection::init(StringRef File, StringRef Data) {
|
||||
FileName = sys::path::filename(File);
|
||||
// The format for the .gnu_debuglink starts with the file name and is
|
||||
|
|
|
@ -259,11 +259,15 @@ class Section : public SectionBase {
|
|||
MAKE_SEC_WRITER_FRIEND
|
||||
|
||||
ArrayRef<uint8_t> Contents;
|
||||
SectionBase *LinkSection = nullptr;
|
||||
|
||||
public:
|
||||
explicit Section(ArrayRef<uint8_t> Data) : Contents(Data) {}
|
||||
|
||||
void accept(SectionVisitor &Visitor) const override;
|
||||
void removeSectionReferences(const SectionBase *Sec) override;
|
||||
void initialize(SectionTableRef SecTable) override;
|
||||
void finalize() override;
|
||||
};
|
||||
|
||||
class OwnedDataSection : public SectionBase {
|
||||
|
@ -456,7 +460,7 @@ public:
|
|||
void setFlagWord(ELF::Elf32_Word W) { FlagWord = W; }
|
||||
void addMember(SectionBase *Sec) { GroupMembers.push_back(Sec); }
|
||||
|
||||
void initialize(SectionTableRef SecTable) override {};
|
||||
void initialize(SectionTableRef SecTable) override{};
|
||||
void accept(SectionVisitor &) const override;
|
||||
void finalize() override;
|
||||
|
||||
|
@ -465,31 +469,18 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class SectionWithStrTab : public Section {
|
||||
const SectionBase *StrTab = nullptr;
|
||||
void setStrTab(const SectionBase *StringTable) { StrTab = StringTable; }
|
||||
|
||||
class DynamicSymbolTableSection : public Section {
|
||||
public:
|
||||
explicit SectionWithStrTab(ArrayRef<uint8_t> Data) : Section(Data) {}
|
||||
void removeSectionReferences(const SectionBase *Sec) override;
|
||||
void initialize(SectionTableRef SecTable) override;
|
||||
void finalize() override;
|
||||
static bool classof(const SectionBase *S);
|
||||
};
|
||||
|
||||
class DynamicSymbolTableSection : public SectionWithStrTab {
|
||||
public:
|
||||
explicit DynamicSymbolTableSection(ArrayRef<uint8_t> Data)
|
||||
: SectionWithStrTab(Data) {}
|
||||
explicit DynamicSymbolTableSection(ArrayRef<uint8_t> Data) : Section(Data) {}
|
||||
|
||||
static bool classof(const SectionBase *S) {
|
||||
return S->Type == ELF::SHT_DYNSYM;
|
||||
}
|
||||
};
|
||||
|
||||
class DynamicSection : public SectionWithStrTab {
|
||||
class DynamicSection : public Section {
|
||||
public:
|
||||
explicit DynamicSection(ArrayRef<uint8_t> Data) : SectionWithStrTab(Data) {}
|
||||
explicit DynamicSection(ArrayRef<uint8_t> Data) : Section(Data) {}
|
||||
|
||||
static bool classof(const SectionBase *S) {
|
||||
return S->Type == ELF::SHT_DYNAMIC;
|
||||
|
|
Loading…
Reference in New Issue