Allow linker scripts when building objects.

Test: m nothing
Test: TreeHugger
Bug: 134581881
Bug: 137267623

Change-Id: If1422372585ec032a9e36eab73a04e98fe1c1b6c
diff --git a/Android.bp b/Android.bp
index 4e44a0d..5c76f5a 100644
--- a/Android.bp
+++ b/Android.bp
@@ -204,6 +204,7 @@
         "cc/gen_test.go",
         "cc/genrule_test.go",
         "cc/library_test.go",
+        "cc/object_test.go",
         "cc/prebuilt_test.go",
         "cc/proto_test.go",
         "cc/test_data_test.go",
diff --git a/cc/cc.go b/cc/cc.go
index b637d3e..7abb72c 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -182,17 +182,6 @@
 	Yacc *YaccProperties
 }
 
-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
-}
-
 // Properties used to compile all C or C++ modules
 type BaseProperties struct {
 	// Deprecated. true is the default, false is invalid.
diff --git a/cc/object.go b/cc/object.go
index 9fa0ac9..33586a4 100644
--- a/cc/object.go
+++ b/cc/object.go
@@ -33,6 +33,20 @@
 	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.
@@ -71,9 +85,13 @@
 	return deps
 }
 
-func (*objectLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags {
+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
 }
 
diff --git a/cc/object_test.go b/cc/object_test.go
new file mode 100644
index 0000000..6ff8a00
--- /dev/null
+++ b/cc/object_test.go
@@ -0,0 +1,31 @@
+// Copyright 2019 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 (
+	"testing"
+)
+
+func TestLinkerScript(t *testing.T) {
+	t.Run("script", func(t *testing.T) {
+		testCc(t, `
+		cc_object {
+			name: "foo",
+			srcs: ["baz.o"],
+			linker_script: "foo.lds",
+		}`)
+	})
+
+}
diff --git a/cc/testing.go b/cc/testing.go
index 5582c8a..a12b520 100644
--- a/cc/testing.go
+++ b/cc/testing.go
@@ -262,6 +262,7 @@
 	mockFS := map[string][]byte{
 		"Android.bp":  []byte(bp),
 		"foo.c":       nil,
+		"foo.lds":     nil,
 		"bar.c":       nil,
 		"baz.o":       nil,
 		"a.proto":     nil,