mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-12 02:47:10 +00:00
[ELF] - Reveal more information in -Map file about assignments.
Currently, LLD print symbol assignment commands to the map file, but it does not do that for assignments that are outside of the section descriptions. Such assignments can affect the layout though. The patch implements the following: * Teaches LLD to print symbol assignments outside of section declaration. * Teaches LLD to print PROVIDE/HIDDEN/PROVIDE hidden commands. In case when symbol is not provided, nothing will be printed. Differential revision: https://reviews.llvm.org/D44894 llvm-svn: 329272
This commit is contained in:
parent
ee01b1d390
commit
e88b76a989
@ -1049,7 +1049,9 @@ void LinkerScript::assignAddresses() {
|
||||
|
||||
for (BaseCommand *Base : SectionCommands) {
|
||||
if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) {
|
||||
Cmd->Addr = Dot;
|
||||
assignSymbol(Cmd, false);
|
||||
Cmd->Size = Dot - Cmd->Addr;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -86,10 +86,8 @@ struct BaseCommand {
|
||||
|
||||
// This represents ". = <expr>" or "<symbol> = <expr>".
|
||||
struct SymbolAssignment : BaseCommand {
|
||||
SymbolAssignment(StringRef Name, Expr E, std::string Loc,
|
||||
std::string CommandString)
|
||||
: BaseCommand(AssignmentKind), Name(Name), Expression(E), Location(Loc),
|
||||
CommandString(CommandString) {}
|
||||
SymbolAssignment(StringRef Name, Expr E, std::string Loc)
|
||||
: BaseCommand(AssignmentKind), Name(Name), Expression(E), Location(Loc) {}
|
||||
|
||||
static bool classof(const BaseCommand *C) {
|
||||
return C->Kind == AssignmentKind;
|
||||
|
@ -175,8 +175,20 @@ void elf::writeMapFile() {
|
||||
OS << right_justify("VMA", W) << ' ' << right_justify("LMA", 9) << ' '
|
||||
<< right_justify("Size", W) << " Align Out In Symbol\n";
|
||||
|
||||
// Print out file contents.
|
||||
for (OutputSection *OSec : OutputSections) {
|
||||
for (BaseCommand *Base : Script->SectionCommands) {
|
||||
if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) {
|
||||
if (Cmd->Provide && !Cmd->Sym)
|
||||
continue;
|
||||
//FIXME: calculate and print LMA.
|
||||
writeHeader(OS, Cmd->Addr, 0, Cmd->Size, 1);
|
||||
OS << Cmd->CommandString << '\n';
|
||||
continue;
|
||||
}
|
||||
|
||||
auto *OSec = dyn_cast<OutputSection>(Base);
|
||||
if (!OSec)
|
||||
continue;
|
||||
|
||||
writeHeader(OS, OSec->Addr, OSec->getLMA(), OSec->Size, OSec->Alignment);
|
||||
OS << OSec->Name << '\n';
|
||||
|
||||
@ -206,6 +218,8 @@ void elf::writeMapFile() {
|
||||
}
|
||||
|
||||
if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) {
|
||||
if (Cmd->Provide && !Cmd->Sym)
|
||||
continue;
|
||||
writeHeader(OS, Cmd->Addr, OSec->getLMA() + Cmd->Addr - OSec->getVA(0),
|
||||
Cmd->Size, 1);
|
||||
OS << Indent8 << Cmd->CommandString << '\n';
|
||||
|
@ -267,8 +267,7 @@ void ScriptParser::readDefsym(StringRef Name) {
|
||||
Expr E = readExpr();
|
||||
if (!atEOF())
|
||||
setError("EOF expected, but got " + next());
|
||||
SymbolAssignment *Cmd = make<SymbolAssignment>(Name, E, getCurrentLocation(),
|
||||
"" /*CommandString*/);
|
||||
SymbolAssignment *Cmd = make<SymbolAssignment>(Name, E, getCurrentLocation());
|
||||
Script->SectionCommands.push_back(Cmd);
|
||||
}
|
||||
|
||||
@ -773,27 +772,31 @@ SymbolAssignment *ScriptParser::readProvideHidden(bool Provide, bool Hidden) {
|
||||
Cmd->Provide = Provide;
|
||||
Cmd->Hidden = Hidden;
|
||||
expect(")");
|
||||
expect(";");
|
||||
return Cmd;
|
||||
}
|
||||
|
||||
SymbolAssignment *ScriptParser::readProvideOrAssignment(StringRef Tok) {
|
||||
size_t OldPos = Pos;
|
||||
SymbolAssignment *Cmd = nullptr;
|
||||
if (peek() == "=" || peek() == "+=") {
|
||||
if (peek() == "=" || peek() == "+=")
|
||||
Cmd = readAssignment(Tok);
|
||||
expect(";");
|
||||
} else if (Tok == "PROVIDE") {
|
||||
else if (Tok == "PROVIDE")
|
||||
Cmd = readProvideHidden(true, false);
|
||||
} else if (Tok == "HIDDEN") {
|
||||
else if (Tok == "HIDDEN")
|
||||
Cmd = readProvideHidden(false, true);
|
||||
} else if (Tok == "PROVIDE_HIDDEN") {
|
||||
else if (Tok == "PROVIDE_HIDDEN")
|
||||
Cmd = readProvideHidden(true, true);
|
||||
|
||||
if (Cmd) {
|
||||
Cmd->CommandString =
|
||||
Tok.str() + " " +
|
||||
llvm::join(Tokens.begin() + OldPos, Tokens.begin() + Pos, " ");
|
||||
expect(";");
|
||||
}
|
||||
return Cmd;
|
||||
}
|
||||
|
||||
SymbolAssignment *ScriptParser::readAssignment(StringRef Name) {
|
||||
size_t OldPos = Pos;
|
||||
StringRef Op = next();
|
||||
assert(Op == "=" || Op == "+=");
|
||||
Expr E = readExpr();
|
||||
@ -801,11 +804,7 @@ SymbolAssignment *ScriptParser::readAssignment(StringRef Name) {
|
||||
std::string Loc = getCurrentLocation();
|
||||
E = [=] { return add(Script->getSymbolValue(Name, Loc), E()); };
|
||||
}
|
||||
|
||||
std::string CommandString =
|
||||
Name.str() + " " +
|
||||
llvm::join(Tokens.begin() + OldPos, Tokens.begin() + Pos, " ");
|
||||
return make<SymbolAssignment>(Name, E, getCurrentLocation(), CommandString);
|
||||
return make<SymbolAssignment>(Name, E, getCurrentLocation());
|
||||
}
|
||||
|
||||
// This is an operator-precedence parser to parse a linker
|
||||
|
@ -1,6 +1,6 @@
|
||||
# REQUIRES: x86
|
||||
|
||||
# RUN: echo '.section .foo.1, "a"; .quad 1' > %t.s
|
||||
# RUN: echo '.quad sym3; .quad sym4; .section .foo.1, "a"; .quad 1' > %t.s
|
||||
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %t.s -o %t.o
|
||||
|
||||
# RUN: ld.lld -o %t %t.o -Map=%t.map --script %s
|
||||
@ -13,33 +13,48 @@ SECTIONS {
|
||||
SHORT(0x1122)
|
||||
LONG(0x11223344)
|
||||
QUAD(0x1122334455667788)
|
||||
PROVIDE_HIDDEN(sym4 = .);
|
||||
. += 0x1000;
|
||||
*(.foo.1)
|
||||
PROVIDE(unused1 = 0xff);
|
||||
HIDDEN(sym6 = .);
|
||||
. += 0x123 *
|
||||
(1 + 1);
|
||||
foo = .;
|
||||
bar = 0x42 - 0x26;
|
||||
}
|
||||
sym1 = .;
|
||||
. += 0x500;
|
||||
sym2 = .;
|
||||
PROVIDE(unused2 = 0xff);
|
||||
PROVIDE(sym3 = 42);
|
||||
}
|
||||
|
||||
# CHECK: VMA LMA Size Align Out In Symbol
|
||||
# CHECK-NEXT: 1000 1000 125d 1 .foo
|
||||
# CHECK-NEXT: 1000 1000 1 1 BYTE ( 0x11 )
|
||||
# CHECK-NEXT: 1001 1001 2 1 SHORT ( 0x1122 )
|
||||
# CHECK-NEXT: 1003 1003 4 1 LONG ( 0x11223344 )
|
||||
# CHECK-NEXT: 1007 1007 8 1 QUAD ( 0x1122334455667788 )
|
||||
# CHECK-NEXT: 100f 100f 1000 1 . += 0x1000
|
||||
# CHECK-NEXT: 200f 200f 8 1 {{.*}}{{/|\\}}map-file.test.tmp.o:(.foo.1)
|
||||
# CHECK-NEXT: 2017 2017 246 1 . += 0x123 * ( 1 + 1 )
|
||||
# CHECK-NEXT: 225d 225d 0 1 foo = .
|
||||
# CHECK-NEXT: 225d 225d 0 1 bar = 0x42 - 0x26
|
||||
# CHECK-NEXT: 2260 2260 0 4 .text
|
||||
# CHECK-NEXT: 2260 2260 0 4 {{.*}}{{/|\\}}map-file.test.tmp.o:(.text)
|
||||
# CHECK-NEXT: 0 0 8 1 .comment
|
||||
# CHECK-NEXT: 0 0 8 1 <internal>:(.comment)
|
||||
# CHECK-NEXT: 0 0 48 8 .symtab
|
||||
# CHECK-NEXT: 0 0 48 8 <internal>:(.symtab)
|
||||
# CHECK-NEXT: 0 0 2f 1 .shstrtab
|
||||
# CHECK-NEXT: 0 0 2f 1 <internal>:(.shstrtab)
|
||||
# CHECK-NEXT: 0 0 9 1 .strtab
|
||||
# CHECK-NEXT: 0 0 9 1 <internal>:(.strtab)
|
||||
# CHECK: VMA LMA Size Align Out In Symbol
|
||||
# CHECK-NEXT: 0 0 1000 1 . = 0x1000
|
||||
# CHECK-NEXT: 1000 1000 125d 1 .foo
|
||||
# CHECK-NEXT: 1000 1000 1 1 BYTE ( 0x11 )
|
||||
# CHECK-NEXT: 1001 1001 2 1 SHORT ( 0x1122 )
|
||||
# CHECK-NEXT: 1003 1003 4 1 LONG ( 0x11223344 )
|
||||
# CHECK-NEXT: 1007 1007 8 1 QUAD ( 0x1122334455667788 )
|
||||
# CHECK-NEXT: 100f 100f 0 1 PROVIDE_HIDDEN ( sym4 = . )
|
||||
# CHECK-NEXT: 100f 100f 1000 1 . += 0x1000
|
||||
# CHECK-NEXT: 200f 200f 8 1 {{.*}}{{/|\\}}map-file.test.tmp.o:(.foo.1)
|
||||
# CHECK-NEXT: 2017 2017 0 1 HIDDEN ( sym6 = . )
|
||||
# CHECK-NEXT: 2017 2017 246 1 . += 0x123 * ( 1 + 1 )
|
||||
# CHECK-NEXT: 225d 225d 0 1 foo = .
|
||||
# CHECK-NEXT: 225d 225d 0 1 bar = 0x42 - 0x26
|
||||
# CHECK-NEXT: 225d 0 0 1 sym1 = .
|
||||
# CHECK-NEXT: 225d 0 500 1 . += 0x500
|
||||
# CHECK-NEXT: 275d 0 0 1 sym2 = .
|
||||
# CHECK-NEXT: 275d 0 0 1 PROVIDE ( sym3 = 42 )
|
||||
# CHECK-NEXT: 2760 2760 10 4 .text
|
||||
# CHECK-NEXT: 2760 2760 10 4 {{.*}}{{/|\\}}map-file.test.tmp.o:(.text)
|
||||
# CHECK-NEXT: 0 0 8 1 .comment
|
||||
# CHECK-NEXT: 0 0 8 1 <internal>:(.comment)
|
||||
# CHECK-NEXT: 0 0 c0 8 .symtab
|
||||
# CHECK-NEXT: 0 0 c0 8 <internal>:(.symtab)
|
||||
# CHECK-NEXT: 0 0 2f 1 .shstrtab
|
||||
# CHECK-NEXT: 0 0 2f 1 <internal>:(.shstrtab)
|
||||
# CHECK-NEXT: 0 0 22 1 .strtab
|
||||
# CHECK-NEXT: 0 0 22 1 <internal>:(.strtab)
|
||||
|
@ -17,6 +17,7 @@ SECTIONS {
|
||||
}
|
||||
|
||||
# CHECK: VMA LMA Size Align Out In Symbol
|
||||
# CHECK-NEXT: 0 0 1000 1 . = 0x1000
|
||||
# CHECK-NEXT: 1000 1000 8 1 .aaa
|
||||
# CHECK-NEXT: 1000 1000 8 1 {{.*}}{{/|\\}}map-file2.test.tmp.o:(.aaa)
|
||||
# CHECK-NEXT: 1008 2000 8 1 .bbb
|
||||
|
Loading…
x
Reference in New Issue
Block a user