Handle GOTTPOFF relocations in delocate.go
These relocations can be emitted for thread-local data. BoringSSL itself doesn't include any thread-local variables that need linker support, but ASAN and MSAN may inject these references in order to handle their own bookkeeping. Change-Id: I0c6e61d244be84d6bee5ccbf7c4ff4ea0f0b90fd Reviewed-on: https://boringssl-review.googlesource.com/15147 Reviewed-by: Adam Langley <agl@google.com>
This commit is contained in:
parent
e5be1740be
commit
e2a701ea1e
@ -125,6 +125,13 @@ func referencesIA32CapDirectly(line string) bool {
|
||||
return i == len(line) || line[i] == '+' || line[i] == '('
|
||||
}
|
||||
|
||||
// threadLocalOffsetFunc describes a function that fetches the offset to symbol
|
||||
// in the thread-local space and writes it to the given target register.
|
||||
type threadLocalOffsetFunc struct {
|
||||
target string
|
||||
symbol string
|
||||
}
|
||||
|
||||
// transform performs a number of transformations on the given assembly code.
|
||||
// See FIPS.md in the current directory for an overview.
|
||||
func transform(lines []string, symbols map[string]bool) (ret []string) {
|
||||
@ -148,6 +155,10 @@ func transform(lines []string, symbols map[string]bool) (ret []string) {
|
||||
// accessor functions need to be emitted outside of the module.
|
||||
var bssAccessorsNeeded []string
|
||||
|
||||
// threadLocalOffsets records the accessor functions needed for getting
|
||||
// offsets in the thread-local storage.
|
||||
threadLocalOffsets := make(map[string]threadLocalOffsetFunc)
|
||||
|
||||
for lineNo, line := range lines {
|
||||
if referencesIA32CapDirectly(line) {
|
||||
panic("reference to OPENSSL_ia32cap_P needs to be changed to indirect via OPENSSL_ia32cap_addr")
|
||||
@ -218,6 +229,30 @@ func transform(lines []string, symbols map[string]bool) (ret []string) {
|
||||
ret = append(ret, line)
|
||||
continue
|
||||
|
||||
case "movq":
|
||||
if !strings.Contains(line, "@GOTTPOFF(%rip)") {
|
||||
ret = append(ret, line)
|
||||
continue
|
||||
}
|
||||
|
||||
// GOTTPOFF are offsets into the thread-local storage
|
||||
// that are stored in the GOT. We have to move these
|
||||
// relocations out of the module, but do not know
|
||||
// whether rax is live at this point. Thus a normal
|
||||
// function call might clobber a register and so we
|
||||
// synthesize different functions for writing to each
|
||||
// target register.
|
||||
//
|
||||
// (BoringSSL itself does not use __thread variables,
|
||||
// but ASAN and MSAN may add these references for their
|
||||
// bookkeeping.)
|
||||
targetRegister := parts[2][1:]
|
||||
symbol := strings.SplitN(parts[1], "@", 2)[0]
|
||||
functionName := fmt.Sprintf("BORINGSSL_bcm_tpoff_to_%s_for_%s", targetRegister, symbol)
|
||||
threadLocalOffsets[functionName] = threadLocalOffsetFunc{target: targetRegister, symbol: symbol}
|
||||
ret = append(ret, "\tcallq "+functionName+"\n")
|
||||
continue
|
||||
|
||||
case ".file":
|
||||
// Do not reorder .file directives. These define
|
||||
// numbered files which are referenced by other debug
|
||||
@ -320,6 +355,22 @@ func transform(lines []string, symbols map[string]bool) (ret []string) {
|
||||
ret = append(ret, "\t.quad OPENSSL_ia32cap_P")
|
||||
}
|
||||
|
||||
// Emit accessors for thread-local offsets.
|
||||
var threadAccessorNames []string
|
||||
for name := range threadLocalOffsets {
|
||||
threadAccessorNames = append(threadAccessorNames, name)
|
||||
}
|
||||
sort.Strings(threadAccessorNames)
|
||||
|
||||
for _, name := range threadAccessorNames {
|
||||
f := threadLocalOffsets[name]
|
||||
|
||||
ret = append(ret, ".type "+name+",@function")
|
||||
ret = append(ret, name+":")
|
||||
ret = append(ret, "\tmovq "+f.symbol+"@GOTTPOFF(%rip), %"+f.target)
|
||||
ret = append(ret, "\tret")
|
||||
}
|
||||
|
||||
// Emit an array for storing the module hash.
|
||||
ret = append(ret, ".type BORINGSSL_bcm_text_hash,@object")
|
||||
ret = append(ret, ".size OPENSSL_ia32cap_addr,32")
|
||||
|
Loading…
Reference in New Issue
Block a user