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>
diff --git a/crypto/fipsmodule/delocate.go b/crypto/fipsmodule/delocate.go
index e28c12a..0a07f0f 100644
--- a/crypto/fipsmodule/delocate.go
+++ b/crypto/fipsmodule/delocate.go
@@ -164,9 +164,12 @@
// referenced and thus needs to be emitted outside the module.
ia32capAddrNeeded := false
- // bssAccessorsNeeded contains the names of BSS symbols for which
- // accessor functions need to be emitted outside of the module.
- var bssAccessorsNeeded []string
+ // bssAccessorsNeeded maps the names of BSS variables for which
+ // accessor functions need to be emitted outside of the module, to the
+ // 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
// offsets in the thread-local storage.
@@ -283,7 +286,7 @@
case ".comm":
p := strings.Split(parts[1], ",")
name := p[0]
- bssAccessorsNeeded = append(bssAccessorsNeeded, name)
+ bssAccessorsNeeded[name] = name
ret = append(ret, line)
case ".section":
@@ -330,6 +333,15 @@
case ".debug", ".note":
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:
panic(fmt.Sprintf("unknown section %q on line %d", section, source.lineNo))
}
@@ -361,12 +373,18 @@
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.
- for _, name := range bssAccessorsNeeded {
+ for _, name := range accessorNames {
funcName := accessorName(name)
ret = append(ret, ".type "+funcName+", @function")
ret = append(ret, funcName+":")
- ret = append(ret, "\tleaq "+name+"(%rip), %rax")
+ ret = append(ret, "\tleaq "+bssAccessorsNeeded[name]+"(%rip), %rax")
ret = append(ret, "\tret")
}
@@ -406,6 +424,45 @@
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
// named name.
func accessorName(name string) string {