Add version_script property

Add version_script property to cc_library to pass a file to
the linker with --version-script.

Change-Id: Ieefb04e15c8dfa72c2eb63b4349f8860222662b2
diff --git a/androidbp/cmd/androidbp.go b/androidbp/cmd/androidbp.go
index 4f9691c..bf24c1b 100644
--- a/androidbp/cmd/androidbp.go
+++ b/androidbp/cmd/androidbp.go
@@ -236,6 +236,19 @@
 	}, nil
 }
 
+func versionScript(name string, prop *bpparser.Property, suffix *string) ([]string, error) {
+	if suffix != nil {
+		name += "_" + *suffix
+	}
+	val, err := valueToString(prop.Value)
+	if err != nil {
+		return nil, err
+	}
+	return []string{
+		fmt.Sprintf("%s += -Wl,--version-script,$(LOCAL_PATH)/%s\n", name, val),
+	}, nil
+}
+
 func (w *androidMkWriter) writeModule(moduleRule string, props []string,
 	disabledBuilds map[string]bool, isHostRule bool) {
 	disabledConditionals := disabledTargetConditionals
diff --git a/androidbp/cmd/soong.go b/androidbp/cmd/soong.go
index 18b8af0..1841381 100644
--- a/androidbp/cmd/soong.go
+++ b/androidbp/cmd/soong.go
@@ -70,6 +70,7 @@
 	"local_include_dirs":  {"LOCAL_C_INCLUDES", prependLocalPath},
 	"export_include_dirs": {"LOCAL_EXPORT_C_INCLUDE_DIRS", prependLocalPath},
 	"suffix":              {"LOCAL_MODULE_STEM", prependLocalModule},
+	"version_script":      {"LOCAL_LDFLAGS", versionScript},
 }
 
 var ignoredProperties = map[string]bool{
diff --git a/cc/builder.go b/cc/builder.go
index ab0e40c..e35cebb 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -277,7 +277,7 @@
 // Generate a rule for compiling multiple .o files, plus static libraries, whole static libraries,
 // and shared libraires, to a shared library (.so) or dynamic executable
 func TransformObjToDynamicBinary(ctx common.AndroidModuleContext,
-	objFiles, sharedLibs, staticLibs, lateStaticLibs, wholeStaticLibs []string,
+	objFiles, sharedLibs, staticLibs, lateStaticLibs, wholeStaticLibs, deps []string,
 	crtBegin, crtEnd string, groupLate bool, flags builderFlags, outputFile string) {
 
 	var ldCmd string
@@ -323,7 +323,7 @@
 		libFlagsList = append(libFlagsList, "-Wl,--end-group")
 	}
 
-	deps := []string{ldCmd}
+	deps = append(deps, ldCmd)
 	deps = append(deps, sharedLibs...)
 	deps = append(deps, staticLibs...)
 	deps = append(deps, lateStaticLibs...)
diff --git a/cc/cc.go b/cc/cc.go
index 2cc4ffb..4b78479 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -947,6 +947,9 @@
 		Static_libs       []string `android:"arch_variant"`
 		Shared_libs       []string `android:"arch_variant"`
 	} `android:"arch_variant"`
+
+	// local file name to pass to the linker as --version_script
+	Version_script string `android:"arch_variant"`
 }
 
 type CCLibrary struct {
@@ -1128,8 +1131,16 @@
 
 	outputFile := filepath.Join(common.ModuleOutDir(ctx), ctx.ModuleName()+sharedLibraryExtension)
 
+	var linkerDeps []string
+
+	if c.LibraryProperties.Version_script != "" {
+		versionScript := filepath.Join(common.ModuleSrcDir(ctx), c.LibraryProperties.Version_script)
+		sharedFlags.LdFlags = append(sharedFlags.LdFlags, "-Wl,--version-script,"+versionScript)
+		linkerDeps = append(linkerDeps, versionScript)
+	}
+
 	TransformObjToDynamicBinary(ctx, objFiles, deps.SharedLibs, deps.StaticLibs,
-		deps.LateStaticLibs, deps.WholeStaticLibs, deps.CrtBegin, deps.CrtEnd, false,
+		deps.LateStaticLibs, deps.WholeStaticLibs, linkerDeps, deps.CrtBegin, deps.CrtEnd, false,
 		ccFlagsToBuilderFlags(flags), outputFile)
 
 	c.out = outputFile
@@ -1398,8 +1409,10 @@
 			ccFlagsToBuilderFlags(flags), afterPrefixSymbols)
 	}
 
+	var linkerDeps []string
+
 	TransformObjToDynamicBinary(ctx, objFiles, deps.SharedLibs, deps.StaticLibs,
-		deps.LateStaticLibs, deps.WholeStaticLibs, deps.CrtBegin, deps.CrtEnd, true,
+		deps.LateStaticLibs, deps.WholeStaticLibs, linkerDeps, deps.CrtBegin, deps.CrtEnd, true,
 		ccFlagsToBuilderFlags(flags), outputFile)
 }