Files
build_soong/cc/object.go
Peter Collingbourne 1c648b8936 Allow sanitize attribute on cc_objects and propagate sanitize attributes into them.
Without this change, we can end up failing to sanitize parts of libraries
that are compiled as cc_objects, such as bcm_object.o in boringssl. This
is normally harmless (except that the sanitizer would fail to detect bugs
in unsanitized code), however boringssl in particular needs to be compiled
with HWASAN enabled in all translation units in order to avoid link errors
with newer toolchains that support HWASAN global instrumentation.

Change-Id: Ib8bd325f76b7852cab435bff79d6945768298a5c
2019-09-26 12:35:06 -07:00

145 lines
4.4 KiB
Go

// Copyright 2016 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package cc
import (
"fmt"
"android/soong/android"
)
//
// Objects (for crt*.o)
//
func init() {
android.RegisterModuleType("cc_object", ObjectFactory)
}
type objectLinker struct {
*baseLinker
Properties ObjectLinkerProperties
}
type ObjectLinkerProperties struct {
// list of modules that should only provide headers for this module.
Header_libs []string `android:"arch_variant,variant_prepend"`
// names of other cc_object modules to link into this module using partial linking
Objs []string `android:"arch_variant"`
// if set, add an extra objcopy --prefix-symbols= step
Prefix_symbols *string
// if set, the path to a linker script to pass to ld -r when combining multiple object files.
Linker_script *string `android:"path,arch_variant"`
}
// cc_object runs the compiler without running the linker. It is rarely
// necessary, but sometimes used to generate .s files from .c files to use as
// input to a cc_genrule module.
func ObjectFactory() android.Module {
module := newBaseModule(android.HostAndDeviceSupported, android.MultilibBoth)
module.sanitize = &sanitize{}
module.linker = &objectLinker{
baseLinker: NewBaseLinker(module.sanitize),
}
module.compiler = NewBaseCompiler()
// Clang's address-significance tables are incompatible with ld -r.
module.compiler.appendCflags([]string{"-fno-addrsig"})
module.stl = &stl{}
return module.Init()
}
func (object *objectLinker) appendLdflags(flags []string) {
panic(fmt.Errorf("appendLdflags on objectLinker not supported"))
}
func (object *objectLinker) linkerProps() []interface{} {
return []interface{}{&object.Properties}
}
func (*objectLinker) linkerInit(ctx BaseModuleContext) {}
func (object *objectLinker) linkerDeps(ctx DepsContext, deps Deps) Deps {
if ctx.useVndk() && ctx.toolchain().Bionic() {
// Needed for VNDK builds where bionic headers aren't automatically added.
deps.LateSharedLibs = append(deps.LateSharedLibs, "libc")
}
deps.HeaderLibs = append(deps.HeaderLibs, object.Properties.Header_libs...)
deps.ObjFiles = append(deps.ObjFiles, object.Properties.Objs...)
return deps
}
func (object *objectLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags {
flags.LdFlags = append(flags.LdFlags, ctx.toolchain().ToolchainClangLdflags())
if lds := android.OptionalPathForModuleSrc(ctx, object.Properties.Linker_script); lds.Valid() {
flags.LdFlags = append(flags.LdFlags, "-Wl,-T,"+lds.String())
flags.LdFlagsDeps = append(flags.LdFlagsDeps, lds.Path())
}
return flags
}
func (object *objectLinker) link(ctx ModuleContext,
flags Flags, deps PathDeps, objs Objects) android.Path {
objs = objs.Append(deps.Objs)
var outputFile android.Path
builderFlags := flagsToBuilderFlags(flags)
if len(objs.objFiles) == 1 {
outputFile = objs.objFiles[0]
if String(object.Properties.Prefix_symbols) != "" {
output := android.PathForModuleOut(ctx, ctx.ModuleName()+objectExtension)
TransformBinaryPrefixSymbols(ctx, String(object.Properties.Prefix_symbols), outputFile,
builderFlags, output)
outputFile = output
}
} else {
output := android.PathForModuleOut(ctx, ctx.ModuleName()+objectExtension)
outputFile = output
if String(object.Properties.Prefix_symbols) != "" {
input := android.PathForModuleOut(ctx, "unprefixed", ctx.ModuleName()+objectExtension)
TransformBinaryPrefixSymbols(ctx, String(object.Properties.Prefix_symbols), input,
builderFlags, output)
output = input
}
TransformObjsToObj(ctx, objs.objFiles, builderFlags, output, flags.LdFlagsDeps)
}
ctx.CheckbuildFile(outputFile)
return outputFile
}
func (object *objectLinker) unstrippedOutputFilePath() android.Path {
return nil
}
func (object *objectLinker) nativeCoverage() bool {
return true
}
func (object *objectLinker) coverageOutputFilePath() android.OptionalPath {
return android.OptionalPath{}
}