Handle BSS sections.
In some modes the compiler will emit a section for BSS symbols and construct the values with labels, alignment and data instructions. This change parses these sections and emits the local versions of each symbol needed to make this work. Change-Id: I8d43ffe4b5b734950aa4287a3dd7c0d2f191f2e4 Reviewed-on: https://boringssl-review.googlesource.com/15206 Reviewed-by: Adam Langley <agl@google.com>
This commit is contained in:
parent
b0d864ee6d
commit
947417a159
@ -164,9 +164,12 @@ func transform(lines []string, symbols map[string]bool) (ret []string) {
|
|||||||
// referenced and thus needs to be emitted outside the module.
|
// referenced and thus needs to be emitted outside the module.
|
||||||
ia32capAddrNeeded := false
|
ia32capAddrNeeded := false
|
||||||
|
|
||||||
// bssAccessorsNeeded contains the names of BSS symbols for which
|
// bssAccessorsNeeded maps the names of BSS variables for which
|
||||||
// accessor functions need to be emitted outside of the module.
|
// accessor functions need to be emitted outside of the module, to the
|
||||||
var bssAccessorsNeeded []string
|
// BSS symbols they point to. For example, “EVP_sha256_once” could map
|
||||||
|
// to “.LEVP_sha256_once_local_target” or “EVP_sha256_once” (if .comm
|
||||||
|
// was used).
|
||||||
|
bssAccessorsNeeded := make(map[string]string)
|
||||||
|
|
||||||
// threadLocalOffsets records the accessor functions needed for getting
|
// threadLocalOffsets records the accessor functions needed for getting
|
||||||
// offsets in the thread-local storage.
|
// offsets in the thread-local storage.
|
||||||
@ -283,7 +286,7 @@ func transform(lines []string, symbols map[string]bool) (ret []string) {
|
|||||||
case ".comm":
|
case ".comm":
|
||||||
p := strings.Split(parts[1], ",")
|
p := strings.Split(parts[1], ",")
|
||||||
name := p[0]
|
name := p[0]
|
||||||
bssAccessorsNeeded = append(bssAccessorsNeeded, name)
|
bssAccessorsNeeded[name] = name
|
||||||
ret = append(ret, line)
|
ret = append(ret, line)
|
||||||
|
|
||||||
case ".section":
|
case ".section":
|
||||||
@ -330,6 +333,15 @@ func transform(lines []string, symbols map[string]bool) (ret []string) {
|
|||||||
case ".debug", ".note":
|
case ".debug", ".note":
|
||||||
ret = append(ret, line)
|
ret = append(ret, line)
|
||||||
|
|
||||||
|
case ".bss":
|
||||||
|
ret = append(ret, line)
|
||||||
|
|
||||||
|
var accessors map[string]string
|
||||||
|
accessors, ret = handleBSSSection(ret, source)
|
||||||
|
for accessor, name := range accessors {
|
||||||
|
bssAccessorsNeeded[accessor] = name
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("unknown section %q on line %d", section, source.lineNo))
|
panic(fmt.Sprintf("unknown section %q on line %d", section, source.lineNo))
|
||||||
}
|
}
|
||||||
@ -361,12 +373,18 @@ func transform(lines []string, symbols map[string]bool) (ret []string) {
|
|||||||
ret = append(ret, "\tjmp "+redirectors[name]+"@PLT")
|
ret = append(ret, "\tjmp "+redirectors[name]+"@PLT")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var accessorNames []string
|
||||||
|
for accessor := range bssAccessorsNeeded {
|
||||||
|
accessorNames = append(accessorNames, accessor)
|
||||||
|
}
|
||||||
|
sort.Strings(accessorNames)
|
||||||
|
|
||||||
// Emit BSS accessor functions. Each is a single LEA followed by RET.
|
// Emit BSS accessor functions. Each is a single LEA followed by RET.
|
||||||
for _, name := range bssAccessorsNeeded {
|
for _, name := range accessorNames {
|
||||||
funcName := accessorName(name)
|
funcName := accessorName(name)
|
||||||
ret = append(ret, ".type "+funcName+", @function")
|
ret = append(ret, ".type "+funcName+", @function")
|
||||||
ret = append(ret, funcName+":")
|
ret = append(ret, funcName+":")
|
||||||
ret = append(ret, "\tleaq "+name+"(%rip), %rax")
|
ret = append(ret, "\tleaq "+bssAccessorsNeeded[name]+"(%rip), %rax")
|
||||||
ret = append(ret, "\tret")
|
ret = append(ret, "\tret")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -406,6 +424,45 @@ func transform(lines []string, symbols map[string]bool) (ret []string) {
|
|||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handleBSSSection reads lines from source until the next section and adds a
|
||||||
|
// local symbol for each BSS symbol found.
|
||||||
|
func handleBSSSection(lines []string, source *lineSource) (map[string]string, []string) {
|
||||||
|
accessors := make(map[string]string)
|
||||||
|
|
||||||
|
for {
|
||||||
|
line, ok := source.Next()
|
||||||
|
if !ok {
|
||||||
|
return accessors, lines
|
||||||
|
}
|
||||||
|
|
||||||
|
parts := strings.Fields(strings.TrimSpace(line))
|
||||||
|
if len(parts) == 0 {
|
||||||
|
lines = append(lines, line)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.HasSuffix(parts[0], ":") {
|
||||||
|
symbol := parts[0][:len(parts[0])-1]
|
||||||
|
localSymbol := ".L" + symbol + "_local_target"
|
||||||
|
|
||||||
|
lines = append(lines, line)
|
||||||
|
lines = append(lines, localSymbol + ":")
|
||||||
|
|
||||||
|
accessors[symbol] = localSymbol
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
switch parts[0] {
|
||||||
|
case ".text", ".section":
|
||||||
|
source.Unread()
|
||||||
|
return accessors, lines
|
||||||
|
|
||||||
|
default:
|
||||||
|
lines = append(lines, line)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// accessorName returns the name of the accessor function for a BSS symbol
|
// accessorName returns the name of the accessor function for a BSS symbol
|
||||||
// named name.
|
// named name.
|
||||||
func accessorName(name string) string {
|
func accessorName(name string) string {
|
||||||
|
Loading…
Reference in New Issue
Block a user