[PATCH] D44004: [ELF] - Show data and assignment commands in the map file.

Rafael Avila de Espindola via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 7 09:57:27 PST 2018


LGTM

George Rimar via Phabricator via llvm-commits
<llvm-commits at lists.llvm.org> writes:

> grimar updated this revision to Diff 137382.
> grimar marked 4 inline comments as done.
> grimar added a comment.
>
> - Addressed review comments.
>
>
> https://reviews.llvm.org/D44004
>
> Files:
>   ELF/LinkerScript.cpp
>   ELF/LinkerScript.h
>   ELF/MapFile.cpp
>   ELF/ScriptParser.cpp
>   test/ELF/linkerscript/map-file.test
>
> Index: test/ELF/linkerscript/map-file.test
> ===================================================================
> --- test/ELF/linkerscript/map-file.test
> +++ test/ELF/linkerscript/map-file.test
> @@ -0,0 +1,38 @@
> +# REQUIRES: x86
> +
> +# RUN: echo ".section .foo.1,\"a\"" > %t.s
> +# RUN: echo ".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
> +# RUN: FileCheck -strict-whitespace %s < %t.map
> +
> +SECTIONS {
> +  . = 0x1000;
> +  .foo : {
> +    BYTE(0x11)
> +    SHORT(0x1122)
> +    LONG(0x11223344)
> +    QUAD(0x1122334455667788)
> +    . += 0x1000;
> +    *(.foo.1)
> +    . += 0x123 *
> +         (1 + 1);
> +    foo = .;
> +    bar = 0x42 - 0x26;
> +  }
> +}
> +
> +# CHECK:      Address          Size             Align Out     In      Symbol
> +# CHECK-NEXT: 0000000000001000 000000000000125d     1 .foo
> +# CHECK-NEXT: 0000000000001000 0000000000000001     1         BYTE ( 0x11 )
> +# CHECK-NEXT: 0000000000001001 0000000000000002     2         SHORT ( 0x1122 )
> +# CHECK-NEXT: 0000000000001003 0000000000000004     4         LONG ( 0x11223344 )
> +# CHECK-NEXT: 0000000000001007 0000000000000008     8         QUAD ( 0x1122334455667788 )
> +# CHECK-NEXT: 000000000000100f 0000000000001000     1         . += 0x1000
> +# CHECK-NEXT: 000000000000200f 0000000000000008     1         {{.*}}{{/|\\}}map-file.test.tmp.o:(.foo.1)
> +# CHECK-NEXT: 0000000000002017 0000000000000246     1         . += 0x123 * ( 1 + 1 )
> +# CHECK-NEXT: 000000000000225d 0000000000000000     1         foo = .
> +# CHECK-NEXT: 000000000000225d 0000000000000000     1         bar = 0x42 - 0x26
> +# CHECK-NEXT: 0000000000002260 0000000000000000     4 .text
> +# CHECK-NEXT: 0000000000002260 0000000000000000     4         {{.*}}{{/|\\}}map-file.test.tmp.o:(.text)
> Index: ELF/ScriptParser.cpp
> ===================================================================
> --- ELF/ScriptParser.cpp
> +++ ELF/ScriptParser.cpp
> @@ -114,6 +114,10 @@
>    std::pair<std::vector<SymbolVersion>, std::vector<SymbolVersion>>
>    readSymbols();
>  
> +  // Concatenates tokens in a [FirstTok, LastTok] into string with Prefix.
> +  std::string buildCommandString(StringRef Prefix, size_t FirstTok,
> +                                 size_t LastTok);
> +
>    // True if a script being read is in a subdirectory specified by -sysroot.
>    bool IsUnderSysroot;
>  
> @@ -773,15 +777,25 @@
>    return Cmd;
>  }
>  
> +std::string ScriptParser::buildCommandString(StringRef Prefix, size_t FirstTok,
> +                                             size_t LastTok) {
> +  return (Prefix + " ").str() +
> +         llvm::join(Tokens.begin() + FirstTok, Tokens.begin() + LastTok, " ");
> +}
> +
>  SymbolAssignment *ScriptParser::readAssignment(StringRef Name) {
> +  size_t OldPos = Pos;
>    StringRef Op = next();
>    assert(Op == "=" || Op == "+=");
>    Expr E = readExpr();
>    if (Op == "+=") {
>      std::string Loc = getCurrentLocation();
>      E = [=] { return add(Script->getSymbolValue(Name, Loc), E()); };
>    }
> -  return make<SymbolAssignment>(Name, E, getCurrentLocation());
> +
> +  SymbolAssignment *Ret = make<SymbolAssignment>(Name, E, getCurrentLocation());
> +  Ret->CommandString = buildCommandString(Name, OldPos, Pos);
> +  return Ret;
>  }
>  
>  // This is an operator-precedence parser to parse a linker
> @@ -935,7 +949,11 @@
>                   .Default(-1);
>    if (Size == -1)
>      return nullptr;
> -  return make<ByteCommand>(readParenExpr(), Size);
> +
> +  size_t OldPos = Pos;
> +  ByteCommand *Ret = make<ByteCommand>(readParenExpr(), Size);
> +  Ret->CommandString = buildCommandString(Tok, OldPos, Pos);
> +  return Ret;
>  }
>  
>  StringRef ScriptParser::readParenLiteral() {
> Index: ELF/MapFile.cpp
> ===================================================================
> --- ELF/MapFile.cpp
> +++ ELF/MapFile.cpp
> @@ -138,11 +138,29 @@
>      OS << OSec->Name << '\n';
>  
>      // Dump symbols for each input section.
> -    for (InputSection *IS : getInputSections(OSec)) {
> -      writeHeader(OS, OSec->Addr + IS->OutSecOff, IS->getSize(), IS->Alignment);
> -      OS << Indent1 << toString(IS) << '\n';
> -      for (Symbol *Sym : SectionSyms[IS])
> -        OS << SymStr[Sym] << '\n';
> +    for (BaseCommand *Base : OSec->SectionCommands) {
> +      if (auto *ISD = dyn_cast<InputSectionDescription>(Base)) {
> +        for (InputSection *IS : ISD->Sections) {
> +          writeHeader(OS, OSec->Addr + IS->OutSecOff, IS->getSize(),
> +                      IS->Alignment);
> +          OS << Indent1 << toString(IS) << '\n';
> +          for (Symbol *Sym : SectionSyms[IS])
> +            OS << SymStr[Sym] << '\n';
> +        }
> +        continue;
> +      }
> +
> +      if (auto *Cmd = dyn_cast<ByteCommand>(Base)) {
> +        writeHeader(OS, OSec->Addr + Cmd->Offset, Cmd->Size, Cmd->Size);
> +        OS << Indent1 << Cmd->CommandString << '\n';
> +        continue;
> +      }
> +
> +      if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) {
> +        writeHeader(OS, OSec->Addr + Cmd->Offset, Cmd->Size, 1);
> +        OS << Indent1 << Cmd->CommandString << '\n';
> +        continue;
> +      }
>      }
>    }
>  }
> Index: ELF/LinkerScript.h
> ===================================================================
> --- ELF/LinkerScript.h
> +++ ELF/LinkerScript.h
> @@ -106,6 +106,14 @@
>  
>    // Holds file name and line number for error reporting.
>    std::string Location;
> +
> +  // Following attributes are used for printing the map file.
> +  // Keeps string representing the command.
> +  std::string CommandString;
> +  // The offset value within the section before execution of assignment.
> +  unsigned Offset;
> +  // The value by which the assignment changed the output section size.
> +  unsigned Size;
>  };
>  
>  // Linker scripts allow additional constraints to be put on ouput sections.
> @@ -183,6 +191,9 @@
>  
>    static bool classof(const BaseCommand *C) { return C->Kind == ByteKind; }
>  
> +  // Keeps string representing the command. Used when printing map file.
> +  std::string CommandString;
> +
>    Expr Expression;
>    unsigned Offset;
>    unsigned Size;
> Index: ELF/LinkerScript.cpp
> ===================================================================
> --- ELF/LinkerScript.cpp
> +++ ELF/LinkerScript.cpp
> @@ -739,7 +739,9 @@
>    for (BaseCommand *Base : Sec->SectionCommands) {
>      // This handles the assignments to symbol or to the dot.
>      if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) {
> +      Cmd->Offset = Dot - Ctx->OutSec->Addr;
>        assignSymbol(Cmd, true);
> +      Cmd->Size = Dot - Ctx->OutSec->Addr - Cmd->Offset;
>        continue;
>      }
>  
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits


More information about the llvm-commits mailing list